package io.geekidea.boot.generator;

import com.baiwang.open.entity.request.node.ImageInvoicesRecogcollectFileBase64Info;
import com.baiwang.open.entity.request.node.SOutputinvoiceInvoiceBalanceInfo;
import com.baiwang.open.entity.request.node.SOutputinvoiceInvoiceInvoiceDetail;
import com.baiwang.open.entity.response.*;
import com.baiwang.open.entity.response.node.SOutputinvoiceQuery;
import com.baiwang.open.exception.BWOpenException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.geekidea.boot.util.StringUtils.JsonSpliceUtil;

import io.geekidea.boot.util.baiwangApi.*;
import io.geekidea.boot.util.baiwangUtils.InvoiceOrderNoGenerator;
import io.geekidea.boot.util.baiwangUtils.InvoiceUtils;
import io.geekidea.boot.util.Base.ObtainNameAndBase64;
import io.geekidea.boot.util.dingtalk.AuthTokenUtil;
import io.geekidea.boot.util.dingtalk.UpdateFormDataUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@SpringBootTest
public class test {

    @Value("${ding-talk.app-key}")
    private String appKey;

    @Value("${ding-talk.app-secret}")
    private String appsecret;

    @Value("${ding-talk.app-type}")
    private String appType;

    @Value("${ding-talk.system-token}")
    private String systemToken;

    @Value("${ding-talk.user-id}")
    private String userId;

    @Value("${ding-talk.form-uuid-open}")
    private String formUuidOpen;


    @Resource
    private ObtainNameAndBase64 obtainAddressAndName;

    @Test
    void test1() throws Exception {

        List<ImageInvoicesRecogcollectFileBase64Info> filesMap = obtainAddressAndName.getFlieBaseAndName("FINST-MYF663B1L4KYHUTL8OY639AVI14H3XR6092FMU");
        log.info("文件名称: " + filesMap.get(0));
        log.info("文件Base64编码: " + filesMap.get(1));
    }

    @Test
    void test2() throws Exception {
        //实例ID
        String instanceId = "dd566580-600f-4a56-ad08-49f2f8afdc7c";
        String downloadUrl = "https://y3uyhm.aliwork.com/ossFileHandle?spm=a2q5o.26736372.0.0.48743c6bNd5Oyr&appType=APP_SL2FWTEHYTU0H9SDON73&fileName=APP_SL2FWTEHYTU0H9SDON73_MDE2NTA5MTgxMTI5NjQ0NDE1X1VXOTY2MzcxUllEWTFUS01CRDZJNzZOMzlTMk8zNkJaTjBWRU1OMQ$$.txt&instId=&type=download&originalFileName=%E6%B5%8B%E8%AF%95%E6%B5%8B%E8%AF%95.txt";
        String name = "发票.pdf";
        String ext = "";
        //拼接目标JSON
        String resultUrl = JsonSpliceUtil.buildTargetJson(downloadUrl, name, ext);

        //获取accessToken
        String accessToken = AuthTokenUtil.getAccessToken(appKey, appsecret).getAccessToken();
        //更新开票表单附件
        UpdateFormDataUtil.updateForm(accessToken, appType, systemToken, userId, formUuidOpen, instanceId, resultUrl);
        System.out.println(resultUrl);
    }

    @Test
    void test3() throws Exception {
        String instanceId = "FINST-WI866HB1J5LYU1WNA74HG65PBJET3FQ4UO3FMO";
        List<ImageInvoicesRecogcollectFileBase64Info> flieBaseAndName = obtainAddressAndName.getFlieBaseAndName(instanceId);
        System.out.println(flieBaseAndName.size());
    }

    /**
     * 开具发票
     * @throws Exception
     */
    @Test
    void invoiceTest()  {
        String invoiceTerminalCode="";//开票终端/数电账号

        String taxationLabel= "";//差额征税标签(数电差额票时必填):01-全额开票,02-差额开票

        String invoiceTypeCode="01";//发票种类编码，01-数电发票(增值税专用发票),02-数电发票(普通发票),
        String orderDateTime="2025-09-11 14:04:00";//订单日期(yyyy-MM-dd HH:mm:ss)
        String payee="云冰收款人";//收款人
        String checker="云冰复核人";//复核人
        String buyerName="北京京城";//发票抬头、购方名称
        String orderNo = InvoiceOrderNoGenerator.generateOrderNo() + "B";//开票单号蓝票

        String pushEmail="18230059805@163.com";//交付邮箱
        String pushPhone="18230059805";//交付手机

        String taxNo="338888888888SMB";//销方税号、纳税人识别号
        String sellerAddress="北京市朝阳区";//销方地址
        String sellerPhone="18230059806";//销方电话
        String sellerBankName="中国银行";//销方开户行
        String sellerBankNumber="6222029090981193821";//销方银行账户

        String buyerTaxNo="";
        String buyerBankNumber="6222029090981193821";//购方银行账户
        String buyerBankName="中国工商银行";//购方开户行
        String buyerTelephone="18230059807";//购方电话
        String buyerAddress="北京市昌平区";//购方地址

        String orderTotalAmount="50000";//发票总金额
        String goodsTaxRate="0.03";//税率
        String goodsTotalPriceTax="";//含税金额
        String goodsTotalPrice="";//不含税金额
        String goodsTotalTax="";//税额
        String deductibleAmount="";//差额扣除额(小数点后2位，传0或者0.00都表示差额征税:0.00，非差额征税传空)

        String balanceType="";//差额凭证类型，凭证类型:01-数电票,02-增值税专用发票,03-增值税普通发票,04-营业税发票,05-财政票据,06-法院裁决书,07-契税完税凭证,08-其他发票类,09-其他扣除凭证
        String balanceElectricNo="";//数电号码:凭证类型为01时必填
        String balanceInvoiceCode="";//发票代码:凭证类型为02、03、04时必填
        String balanceInvoiceNo="";//发票号码:凭证类型为02、03、04时必填
        String balanceVoucherNo="";//差额扣除凭证号码（如发票号码、完税凭证号等）

        String goodsName="测试商品名称";
        String goodsSpecification="测试规格型号";//规格型号
        String goodsUnit="元";// 单位
        String goodsQuantity="10";// 数量
        String goodsPrice="5000";// 单价
        String remarks="测试发票备注";// 备注


        try {
//            SOutputinvoiceInvoiceResponse response = Invoice.issueAnInvoice(
//                    invoiceTerminalCode,
//                    taxationLabel,
//                    invoiceTypeCode,
//                    orderDateTime,
//                    payee,
//                    checker,
//                    buyerName,
//                    orderNo,
//                    pushEmail,
//                    pushPhone,
//                    taxNo,
//                    sellerAddress,
//                    sellerPhone,
//                    sellerBankName,
//                    sellerBankNumber,
//                    buyerTaxNo,
//                    buyerBankNumber,
//                    buyerBankName,
//                    buyerTelephone,
//                    buyerAddress,
//                    orderTotalAmount,
//                    goodsTaxRate,
//                    goodsTotalPriceTax,
//                    goodsTotalPrice,
//                    goodsTotalTax,
//                    deductibleAmount,
//                    balanceType,
//                    balanceElectricNo,
//                    balanceInvoiceCode,
//                    balanceInvoiceNo,
//                    balanceVoucherNo,
//                    goodsName,
//                    goodsSpecification,
//                    goodsUnit,
//                    goodsQuantity,
//                    goodsPrice,
//                    remarks
//            );
//            System.out.println("response：:" + response);
        } catch (BWOpenException e) {
            System.out.println("开放平台错误码：" + e.getCode()); // 捕获百望云开放平台异常：打印开放平台错误码
            System.out.println("开放平台异常信息：" + e.getMessage()); // 捕获百望云开放平台异常：打印开放平台错误信息
            System.out.println("业务端错误码：" + e.getSubCode()); // 捕获百望云开放平台异常：打印业务端错误码
            System.out.println("业务端异常信息：" + e.getSubMessage()); // 捕获百望云开放平台异常：打印业务端错误信息（详见文档“五、错误码”）
        }
    }

    /**
     * 快捷冲红
     */
    @Test
    void fastRedTest4()  {


        String orderNo = InvoiceOrderNoGenerator.generateOrderNo() + "R";//红票

        String originalDigitInvoiceNo = "20009110058600006729";//数电发票号码
        String originalSerialNo = "25090915543423001495";//原蓝票请求流水号

        String drawerId = "云冰";//开票员id
        String taxNo = "338888888888SMB";//销方税号
        String pushPhone = "18230059805";//交付手机
        String pushEmail = "18230059805@163.com";//交付邮箱

//        String serialNo = invoice.issueAnInvoice(orderNo);
        SOutputinvoiceFastRedResponse sOutputinvoiceFastRedResponse = null;

        try {
//            sOutputinvoiceFastRedResponse = FastRed.fastRedInvoice(pushPhone, originalSerialNo, drawerId, originalDigitInvoiceNo, taxNo, pushEmail, orderNo);
        } catch (BWOpenException e) {
            System.out.println("开放平台错误码：" + e.getCode()); // 捕获百望云开放平台异常：打印开放平台错误码
            System.out.println("开放平台异常信息：" + e.getMessage()); // 捕获百望云开放平台异常：打印开放平台错误信息
            System.out.println("业务端错误码：" + e.getSubCode()); // 捕获百望云开放平台异常：打印业务端错误码
            System.out.println("业务端异常信息：" + e.getSubMessage()); // 捕获百望云开放平台异常：打印业务端错误信息（详见文档“五、错误码”）
        }


        // 检查响应对象是否为null
        if (sOutputinvoiceFastRedResponse != null) {
            System.out.println("接口调用是否成功：" + sOutputinvoiceFastRedResponse.getSuccess());

            // 检查ErrorResponse是否为null
            if (sOutputinvoiceFastRedResponse.getErrorResponse() != null) {
                System.out.println("错误信息：" + sOutputinvoiceFastRedResponse.getErrorResponse().getSubMessage());
                System.out.println("错误信息2：" + sOutputinvoiceFastRedResponse.getErrorResponse().getMessage());
            } else {
                System.out.println("ErrorResponse为null");
            }

            // 检查Response是否为null
            if (sOutputinvoiceFastRedResponse.getResponse() != null) {
                System.out.println("申请流水号(红票)为：" + sOutputinvoiceFastRedResponse.getResponse().getSerialNo());
                System.out.println("开票单号(红票)为：" + sOutputinvoiceFastRedResponse.getResponse().getOrderNo());
                System.out.println("红字确认单申请号：" + sOutputinvoiceFastRedResponse.getResponse().getRedConfirmSerialNo());

            } else {
                System.out.println("Response为null");
            }
        } else {
            System.out.println("本次发票红冲返回内容为null");
        }
    }

    /**
     * 交付发票
     */
    @Test
    void pushTest5() {
        String taxNo = "338888888888SMB",      // 必填 销方税号
                //下面发票号码填写任意一个即可
                invoiceCode = "",              // 非必填 发票代码
                invoiceNo = "",                // 非必填 发票号码
                digitInvoiceNo = "200091100586000066541",           // 非必填 数电发票号码

                pushPhone = "18230059805",     // 非必填 交付手机
                pushEmail = "";                // 非必填 交付邮箱

        try {
            SOutputinvoicePushResponse sOutputinvoicePushResponse = Push.pushInvoice(taxNo, invoiceCode, invoiceNo, digitInvoiceNo, pushPhone, pushEmail);
            if(sOutputinvoicePushResponse.getSuccess()){
                System.out.println("发票交付成功" );
            }else{
                System.out.println("发票交付失败" );
            }

        } catch (BWOpenException e) {
            System.out.println("发票交付失败3" );
            System.out.println("开放平台错误码：" + e.getCode()); // 捕获百望云开放平台异常：打印开放平台错误码
            System.out.println("开放平台异常信息：" + e.getMessage()); // 捕获百望云开放平台异常：打印开放平台错误信息
            System.out.println("业务端错误码：" + e.getSubCode()); // 捕获百望云开放平台异常：打印业务端错误码
            System.out.println("业务端异常信息：" + e.getSubMessage()); // 捕获百望云开放平台异常：打印业务端错误信息（详见文档“五、错误码”）
        }
    }

    /**
     * 重新开票
     */
    @Test
    void retryTest(){
        String taxNo = "338888888888SMB",      // 必填 销方税号
                // 下面发票号码填写任意一个即可
                serialNo = "25090914175923001309",              // 非必填 申请流水号
                orderNo = "",                // 非必填 开票单号

                invoiceTerminalCode = "",     // 非必填 开票终端/数电账号
                isForceRepush = "";    // 非必填 	强制开票标志:0-否(默认),1-是

        try {
            SOutputinvoiceRetryResponse sOutputinvoiceRetryResponse = Retry.retryInvoice(taxNo, serialNo, orderNo, invoiceTerminalCode, isForceRepush);
            System.out.println("申请流水号"+ sOutputinvoiceRetryResponse.getResponse().getSerialNo());
        } catch (BWOpenException e) {
            System.out.println("开放平台错误码：" + e.getCode()); // 捕获百望云开放平台异常：打印开放平台错误码
            System.out.println("开放平台异常信息：" + e.getMessage()); // 捕获百望云开放平台异常：打印开放平台错误信息
            System.out.println("业务端错误码：" + e.getSubCode()); // 捕获百望云开放平台异常：打印业务端错误码
            System.out.println("业务端异常信息：" + e.getSubMessage()); // 捕获百望云开放平台异常：打印业务端错误信息（详见文档“五、错误码”）
        }
    }

    /**
     * 查询开票结果
     */
    @Test
    void queryTest()  {
        String taxNo = "338888888888SMB";     // 必填 销方税号
        //下面发票号码填写任意一个即可
        List<String> serialNos=new ArrayList<>();//List<String>, 申请流水号列表(最多支持100个，申请流水号/开票单号，任选一项必填，都传值时，优先使用申请流水号查询)
        serialNos.add("25090916200323001538");
        List<String> orderNos=new ArrayList<>();//List<String>, 开票单号列表(最多支持100个，申请流水号/开票单号，任选一项必填)
        String detailMark = "0";//是否需要发票明细:0-不需要,1-需要(默认不需要)
        String status;
        try {
            SOutputinvoiceQueryResponse sOutputinvoiceQueryResponse = Query.queryInvoice(taxNo, serialNos, orderNos, detailMark);
            List<SOutputinvoiceQuery> responseList = sOutputinvoiceQueryResponse.getResponse();
            status = InvoiceUtils.getFirstStatus(responseList);
            System.out.println("开票状态：" +status);
            switch (status) {
                case "02":
                    //TODO 重开发票接口
                    System.out.println("发票重开");
                case "00":
                case "04":
                    //TODO 两个中间态继续查询
                    System.out.println("继续查询");
                    queryTest();
                case "01":
                case "03":
                    //TODO 开票完成和发票已作废状态，停止查询
                    System.out.println("发票已开票完成、或已作废");

            }
        } catch (BWOpenException e) {
            System.out.println("开放平台错误码：" + e.getCode()); // 捕获百望云开放平台异常：打印开放平台错误码
            System.out.println("开放平台异常信息：" + e.getMessage()); // 捕获百望云开放平台异常：打印开放平台错误信息
            System.out.println("业务端错误码：" + e.getSubCode()); // 捕获百望云开放平台异常：打印业务端错误码
            System.out.println("业务端异常信息：" + e.getSubMessage()); // 捕获百望云开放平台异常：打印业务端错误信息（详见文档“五、错误码”）
        }

    }
    @Test
    void StringTest()   {
        String s = generateFileInfoJson("https://sales.baiwang.com/files/digitInvoice.pdf", "digitInvoice.pdf", "https://sales.baiwang.com/files/digitInvoice.pdf", "pdf");
        System.out.println(s);
    }

    public static String generateFileInfoJson(String downloadUrl, String name, String previewUrl, String ext) {
        // 使用字符串拼接构建JSON
        // 注意：实际项目中推荐使用JSON库（如Jackson、Gson）来处理JSON
        StringBuilder jsonBuilder = new StringBuilder();
        jsonBuilder.append("{")
                .append("\"downloadUrl\": \"").append(escapeJson(downloadUrl)).append("\",")
                .append("\"name\": \"").append(escapeJson(name)).append("\",")
                .append("\"previewUrl\": \"").append(escapeJson(previewUrl)).append("\",")
                .append("\"url\": \"").append(escapeJson(downloadUrl)).append("\",")
                .append("\"ext\": \"").append(escapeJson(ext)).append("\"")
                .append("}");

        return jsonBuilder.toString();
    }

    /**
     * 简单的JSON转义处理
     * @param value 需要转义的字符串
     * @return 转义后的字符串
     */
    private static String escapeJson(String value) {
        if (value == null) {
            return "";
        }
        return value.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\b", "\\b")
                .replace("\f", "\\f")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }
    @Test
    void iTest() {

        try {
//            String json = "[  {    \"balanceVoucherNo\": \"4545\",    \"balanceType\": \"01\",    \"balanceDeductAmount\": 454,    \"balanceNo\": \"\",    \"balanceIssueDate\": \"2025-09-17\",    \"balanceInvoiceNo\": \"454\",    \"balanceTotalAmount\": 454554,    \"balanceSource\": \"0\",    \"balanceElectricNo\": \"544\",    \"balanceInvoiceCode\": \"44\",    \"balanceRemarks\": \"4554\"  },  {    \"balanceVoucherNo\": \"4554\",    \"balanceType\": \"02\",    \"balanceDeductAmount\": 454,    \"balanceNo\": \"\",    \"balanceIssueDate\": \"2025-09-17\",    \"balanceInvoiceNo\": \"45\",    \"balanceTotalAmount\": 545,    \"balanceSource\": \"0\",    \"balanceElectricNo\": \"54545\",    \"balanceInvoiceCode\": \"54\",    \"balanceRemarks\": \"55445\"  },  {    \"balanceVoucherNo\": \"545\",    \"balanceType\": \"03\",    \"balanceDeductAmount\": 45,    \"balanceNo\": \"\",    \"balanceIssueDate\": \"2025-09-17\",    \"balanceInvoiceNo\": \"554\",    \"balanceTotalAmount\": 454,    \"balanceSource\": \"0\",    \"balanceElectricNo\": \"54454\",    \"balanceInvoiceCode\": \"5454\",    \"balanceRemarks\": \"4\"  }]";
//            List<SOutputinvoiceInvoiceBalanceInfo> balanceInfoList = convertJsonToBalanceInfoList(json);
//
//            System.out.println(balanceInfoList);

            String  test="[  {    \"goodsName\": \"*简称*项目名称\",    \"goodsPersonalCode\": \"商品编码\",    \"goodsCode\": \"税收分类编码\",    \"goodsQuantity\": 2,    \"goodsPrice\": 250,    \"goodsTaxRate\": 0.03,    \"goodsTotalPriceTax\": 500,    \"goodsTotalTax\": 14.56,    \"goodsSpecification\": \"规格型号\",    \"goodsUnit\": \"单位\",    \"invoiceLineNature\": \"\"  },  {    \"goodsName\": \"*简称*项目名称\",    \"goodsPersonalCode\": \"商品编码\",    \"goodsCode\": \"税收分类编码\",    \"goodsQuantity\": 3,    \"goodsPrice\": 233.33,    \"goodsTaxRate\": 0.05,    \"goodsTotalPriceTax\": 700,    \"goodsTotalTax\": 33.33,    \"goodsSpecification\": \"规格型号\",    \"goodsUnit\": \"单位\",    \"invoiceLineNature\": \"\"  },  {    \"goodsName\": \"*简称*项目名称\",    \"goodsPersonalCode\": \"商品编码\",    \"goodsCode\": \"税收分类编码\",    \"goodsQuantity\": 5,    \"goodsPrice\": 180,    \"goodsTaxRate\": 0.06,    \"goodsTotalPriceTax\": 900,    \"goodsTotalTax\": 50.94,    \"goodsSpecification\": \"规格型号\",    \"goodsUnit\": \"单位\",    \"invoiceLineNature\": \"\"  }]";
            List<SOutputinvoiceInvoiceInvoiceDetail> invoiceDetail =convertJsonToInvoiceDetail(test);
            System.out.println(invoiceDetail);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public List<SOutputinvoiceInvoiceBalanceInfo> convertJsonToBalanceInfoList(String jsonStr) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(jsonStr, new TypeReference<List<SOutputinvoiceInvoiceBalanceInfo>>() {});
    }

    public List<SOutputinvoiceInvoiceInvoiceDetail> convertJsonToInvoiceDetail(String jsonStr) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(jsonStr, new TypeReference<List<SOutputinvoiceInvoiceInvoiceDetail>>() {});
    }
}
